---
title: Module Initializers
---

The module initializer function, `init`, is special in that it executes only once - when you publish the associated module - and must have the following properties:

- Function name must be `init`
- The parameter list must end with either a `&mut TxContext` or a `&TxContext` type
- No return values
- Private visibility
- Optionally, the parameter list starts by accepting the module's one-time witness by value

For example, the following `init` functions are all valid:

- `fun init(ctx: &TxContext)`
- `fun init(ctx: &mut TxContext)`
- `fun init(otw: EXAMPLE, ctx: &TxContext)`
- `fun init(otw: EXAMPLE, ctx: &mut TxContext)`

Every function that fits this criteria will be run when the package is first published, and at no other time, including when the package is upgraded.  This means that an `init` function that was introduced during an upgrade (to a new or existing module) will never run.

The following example demonstrates a valid `init` function in a module:

```move
module examples::one_timer {
    use sui::transfer;
    use sui::object::{Self, UID};
    use sui::tx_context::{Self, TxContext};

    /// The one of a kind - created in the module initializer.
    struct CreatorCapability has key {
        id: UID
    }

    /// This function is only called once on module publish.
    /// Use it to make sure something has happened only once, like
    /// here - only module author will own a version of a
    /// `CreatorCapability` struct.
    fun init(ctx: &mut TxContext) {
        transfer::transfer(CreatorCapability {
            id: object::new(ctx),
        }, tx_context::sender(ctx))
    }
}
```
